package com.df.excel_export.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.df.excel_export.excel_table.ExcelSheet;
import com.df.excel_export.excel_table.ExcelTableStructure;
import com.df.excel_export.excel_table.HHeader;
import com.df.excel_export.excel_table.RowData;
import com.df.excel_export.graph.OrthogonalGraph;
import com.df.excel_export.utils.ExcelTools;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ExcelTableManager {
    public static Lock lock = new ReentrantLock();



    //所有项目表结构数据缓存{文件名(不包含文件扩展名)：文件信息}
    public static Map<String, ExcelTableStructure> excelTableCache = new HashMap<>();
    //所有项目下的excel文件元数据缓存，按项目分组{项目名：{文件全路径：文件信息}}
    public static Map<String, Map<String,ExcelTableStructure>> projectExcelMetaCaches = new HashMap<>();
    //所有夏目下的枚举数据
    public static Map<String, ProjectEnums> projectEnums = new HashMap<>();
    //{projectName:{表文件路径:{行：行数据}}}
    public static Map<String, Map<String, Map<Integer, RowData>>> projectTableDatas  = new HashMap<>();


    public static Map<String, OrthogonalGraph<String>> projectDepends = new HashMap<>();


    //依赖图
//    OrthogonalGraph<String> graph = new OrthogonalGraph<>();

    public static Map<String,ExcelTableStructure> getProjectExcelMeta(String projectName){
        if(projectExcelMetaCaches.containsKey(projectName)){
            return projectExcelMetaCaches.get(projectName);
        }
        Map<String,ExcelTableStructure> chache = null;
        //检查有没有本地缓存
        String property = System.getProperty("user.dir");
        String dir = property+File.separator+"data"+File.separator+"meta";
        String projectCacheFileName = dir+File.separator+projectName+".meta";
        File file = new File(projectCacheFileName);
        if(file.exists()){
            try {
                String s = Files.readString(Paths.get(projectCacheFileName), StandardCharsets.UTF_8);
                Map<String,Object> map = JSON.parseObject(s, Map.class);
                chache = new HashMap<>();
                projectExcelMetaCaches.put(projectName,chache);
                for (Map.Entry<String, Object> en : map.entrySet()) {
                    if(en.getValue() instanceof JSONObject){
                        JSONObject jo = (JSONObject) en.getValue();
                        ExcelTableStructure javaObject = jo.toJavaObject(ExcelTableStructure.class);
                        ExcelSheet table = javaObject.getTable();
                        if(table!=null){
                            List<HHeader> hHeaders = table.getHHeaders();
                            if(hHeaders!=null && !hHeaders.isEmpty()){
                                for (HHeader hHeader : hHeaders) {
                                    table.getHHeaders2().put(hHeader.getCol(),hHeader);
                                }
                            }
                        }
                        chache.put(en.getKey(),javaObject);
                    }

                }
                projectExcelMetaCaches.put(projectName, chache);
            } catch (Exception e) {
                chache = null;
                e.printStackTrace();
            }
        }
        return chache;
    }

    public static void   saveProjectExcelMeta(String projectName,Map<String,ExcelTableStructure> cache){
        if(cache==null|| cache.isEmpty()){
            return;
        }

        String property = System.getProperty("user.dir");
        String dir = property+File.separator+"data"+File.separator+"meta";
        String projectCacheFileName = dir+File.separator+projectName+".meta";
        String chacheStr = JSON.toJSONString(cache, true);
        File file = new File(dir);
        if(!file.exists()){
            try {
                file.mkdirs();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            Files.writeString(Paths.get(projectCacheFileName),chacheStr, StandardOpenOption.CREATE,StandardOpenOption.WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static ProjectEnums getProjectEnums(String projectName){
        if(projectEnums.containsKey(projectName)){
            return projectEnums.get(projectName);
        }
        //检查有没有本地缓存
        String property = System.getProperty("user.dir");
        String dir = property+File.separator+"data"+File.separator+"enums";
        String projectCacheFileName = dir+File.separator+projectName+".enums";
        File file = new File(projectCacheFileName);
        if(file.exists()){
            try {
                String s = Files.readString(Paths.get(projectCacheFileName), StandardCharsets.UTF_8);
                ProjectEnums enums = JSON.parseObject(s, ProjectEnums.class);
//                chache = new HashMap<>();
//                for (Map.Entry<String, Object> en : map.entrySet()) {
//                    if(en.getValue() instanceof JSONObject){
//                        JSONObject jo = (JSONObject) en.getValue();
//                        ExcelEnum javaObject = jo.toJavaObject(ExcelEnum.class);
//                        chache.put(en.getKey(),javaObject);
//                    }
//
//                }
                projectEnums.put(projectName, enums);
            } catch (Exception e) {
                ExcelTools.addExceptionMsg(e);
                e.printStackTrace();
            }
        }
        if(projectEnums.containsKey(projectName)){
            return projectEnums.get(projectName);
        }else {
            projectEnums.put(projectName,new ProjectEnums());
        }
        return projectEnums.get(projectName);
    }

    public static void   saveProjectEnum(String projectName,ProjectEnums enums){
        if(enums==null){
            return;
        }

        String property = System.getProperty("user.dir");
        String dir = property+File.separator+"data"+File.separator+"enums";
        String projectCacheFileName = dir+File.separator+projectName+".enums";
        String chacheStr = JSON.toJSONString(enums, true);
        File file = new File(dir);
        if(!file.exists()){
            try {
                file.mkdirs();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            Files.writeString(Paths.get(projectCacheFileName),chacheStr, StandardOpenOption.CREATE,StandardOpenOption.WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
